package com.slipper.system.flow.service;

import java.util.ArrayList;
import java.util.List;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import com.slipper.constants.Constants;
import com.slipper.constants.FlowConstants;
import com.slipper.core.transaction.ReadTransactional;
import com.slipper.core.transaction.WriteTransactional;
import com.slipper.system.employee.bo.EmployeeBO;
import com.slipper.system.flow.bo.FlowInstBO;
import com.slipper.system.employee.dao.EmployeeDao;
import com.slipper.system.flow.dao.FlowInstDao;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;

import com.slipper.system.flow.dao.FlowPendingDao;
import com.slipper.system.flow.bo.FlowPendingBO;

import com.slipper.util.Tool;

@Service
@ReadTransactional
public class FlowPendingService {
    @Resource
    private FlowPendingDao flowPendingDao;
    @Resource
    private FlowInstDao flowInstDao;
    @Resource
    private EmployeeDao employeeDao;

    public FlowPendingBO queryBy(String id){
        return flowPendingDao.queryBy(id);
    }

    public List<FlowPendingBO> queryList(FlowPendingBO bo){
        return flowPendingDao.queryList(bo);
    }

    public PageInfo<FlowPendingBO> queryPage(FlowPendingBO bo){
        PageHelper.startPage(bo.getPageNumber(), bo.getPageSize());
        return new PageInfo<>(flowPendingDao.queryList(bo));
    }

    @WriteTransactional
    public int save(FlowPendingBO bo){
        int result;
        if (bo.getId() != null && !"".equals(bo.getId())) {
            result = flowPendingDao.update(bo);
        } else {
            bo.setId(Tool.getUUID());
            result = flowPendingDao.insert(bo);
        }
        if (Tool.isBlank(bo.getIfRead())) {
            bo.setIfRead(Constants.NO);
        }
        return result;
    }

    @WriteTransactional
    public int delete(FlowPendingBO bo){
        return flowPendingDao.delete(bo);
    }

    public FlowPendingBO queryByOne(FlowPendingBO bo) {
        return flowPendingDao.queryByOne(bo);
    }

    @WriteTransactional
    public int deleteByInstId(String instId) {
        return flowPendingDao.deleteByInstId(instId);
    }

    @WriteTransactional
    public int saveRead(FlowPendingBO bo) {
        FlowInstBO flowInst = this.flowInstDao.queryBy(bo.getInstId());
        if (flowInst == null) {
            return 0;
        }

        String[] currEmpIds = bo.getReaderIds().split(",");

        EmployeeBO qo = new EmployeeBO();
        qo.setIds(currEmpIds);
        List<EmployeeBO> employeeList = employeeDao.queryByIds(qo);

        List<FlowPendingBO> pendingList = new ArrayList<>();
        employeeList.forEach(employee -> {
            FlowPendingBO pending = new FlowPendingBO();
            pending.setId(Tool.getUUID());
            pending.setFlowId(flowInst.getFlowId());
            pending.setFlowName(flowInst.getFlowName());
            pending.setTitle(flowInst.getTitle());
            pending.setInstId(flowInst.getId());
            pending.setPendingTime(System.currentTimeMillis());
            pending.setCurrManId(employee.getId());
            pending.setCurrOrgId(employee.getOrganizationId());
            pending.setIfRead(Constants.YES);
            pending.setIfSupervise(Constants.NO);
            pending.setStatus(FlowConstants.FlowPending.STATUS_PENDING);
            pendingList.add(pending);
        });

        return flowPendingDao.saveReads(pendingList);
    }

    @WriteTransactional
    public int saveSupervise(FlowPendingBO bo) {
        return flowPendingDao.saveSupervise(bo);
    }

    @WriteTransactional
    public int readPending(FlowPendingBO bo) {
        return flowPendingDao.readPending(bo);
    }

    @WriteTransactional
    public void updateRead(String instNodeId) {
        flowPendingDao.updateRead(instNodeId, System.currentTimeMillis());
    }

    public PageInfo<FlowPendingBO> queryPendedPage(FlowPendingBO bo) {
        PageHelper.startPage(bo.getPageNumber(), bo.getPageSize());
        return new PageInfo<>(flowPendingDao.queryPendedPage(bo));
    }

    public FlowPendingBO queryByInstNodeId(String instNodeId) {
        return flowPendingDao.queryByInstNodeId(instNodeId);
    }
}
